from functools import wraps
from flask import request, jsonify, current_app, g
from flask_jwt_extended import verify_jwt_in_request, get_jwt_identity, jwt_required
from app.models.admin import Admin
from app.models import User, Activity, UserRelation
from app.utils.response import error_response

def login_required(f):
    """用户登录验证装饰器"""
    @wraps(f)
    def decorated(*args, **kwargs):
        try:
            verify_jwt_in_request()
            user_id = get_jwt_identity()
            # 确保user_id是整数类型
            user_id = int(user_id) if user_id else None
            g.user_id = user_id
            g.current_user_id = user_id  # 为了兼容性同时设置两个变量
            return f(*args, **kwargs)
        except Exception as e:
            current_app.logger.error(f"用户登录验证异常: {str(e)}")
            return jsonify({'code': 401, 'message': '请先登录', 'data': None}), 401
    return decorated

def admin_login_required(f):
    """管理员登录验证装饰器"""
    @wraps(f)
    def decorated(*args, **kwargs):
        try:
            current_app.logger.debug(f"验证管理员登录: {request.path}")
            current_app.logger.debug(f"请求头: {request.headers}")
            current_app.logger.debug(f"Authorization: {request.headers.get('Authorization')}")
            
            verify_jwt_in_request()
            user_id = get_jwt_identity()
            current_app.logger.debug(f"JWT验证通过，用户ID: {user_id}")
            
            # 将字符串类型的user_id转换为整数
            user_id = int(user_id)
            
            # 这里需要检查用户是否为管理员，暂时简化处理
            admin = Admin.query.filter_by(id=user_id).first()
            if not admin:
                current_app.logger.debug(f"用户ID {user_id} 不是管理员")
                return jsonify({'code': 403, 'message': '权限不足', 'data': None}), 403
            g.admin_id = user_id
            return f(*args, **kwargs)
        except Exception as e:
            current_app.logger.error(f"管理员验证异常: {str(e)}")
            return jsonify({'code': 401, 'message': '请先登录', 'data': None}), 401
    return decorated

def permission_required(permission):
    """权限验证装饰器"""
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            try:
                # 验证JWT令牌
                verify_jwt_in_request()
                # 获取身份信息
                admin_id = get_jwt_identity()
                # 查询管理员
                admin = Admin.query.get(admin_id)
                if not admin or not admin.is_active:
                    return jsonify({'code': 401, 'message': '无效的管理员账号'}), 401
                
                # 检查权限
                if not admin.has_permission(permission):
                    return jsonify({'code': 403, 'message': '权限不足'}), 403
                
                return f(*args, **kwargs)
            except Exception as e:
                current_app.logger.error(f"权限验证异常: {str(e)}")
                return jsonify({'code': 401, 'message': '请先登录'}), 401
        return decorated_function
    return decorator

def user_required(f):
    """用户认证装饰器"""
    @wraps(f)
    @jwt_required()
    def decorated_function(*args, **kwargs):
        try:
            current_user_id = get_jwt_identity()
            user = User.query.get(current_user_id)
            
            if not user or not user.is_active:
                return error_response('用户不存在或已被禁用', 401)
            
            g.current_user = user
            g.current_user_id = current_user_id
            return f(*args, **kwargs)
        except Exception as e:
            return error_response('认证失败', 401)
    
    return decorated_function

def activity_organizer_required(f):
    """活动组织者权限校验装饰器"""
    @wraps(f)
    @user_required
    def decorated_function(activity_id, *args, **kwargs):
        try:
            activity = Activity.query.get(activity_id)
            if not activity:
                return error_response('活动不存在', 404)
            
            if activity.organizer_id != g.current_user_id:
                return error_response('无权限操作此活动', 403)
            
            g.current_activity = activity
            return f(activity_id, *args, **kwargs)
        except Exception as e:
            return error_response('权限校验失败', 500)
    
    return decorated_function

def check_blacklist(activity_id, user_id):
    """检查用户是否被活动组织者拉黑"""
    activity = Activity.query.get(activity_id)
    if not activity:
        return False, "活动不存在"
    
    # 检查是否被拉黑
    is_blacklisted = UserRelation.is_blacklisted(activity.organizer_id, user_id)
    if is_blacklisted:
        return False, "您已被活动组织者拉黑，无法参与此活动"
    
    return True, None

def validate_relation_type(relation_type):
    """验证关系类型"""
    if relation_type not in ['friend', 'blacklist']:
        return False, "关系类型必须是 'friend' 或 'blacklist'"
    return True, None

def get_user_by_id(user_id):
    """根据ID获取用户"""
    user = User.query.get(user_id)
    if not user:
        return None, "用户不存在"
    if not user.is_active:
        return None, "用户已被禁用"
    return user, None 

def admin_required(f):
    """管理员权限验证装饰器"""
    @wraps(f)
    def decorated(*args, **kwargs):
        try:
            current_app.logger.debug(f"验证管理员权限: {request.path}")
            
            verify_jwt_in_request()
            user_id = get_jwt_identity()
            current_app.logger.debug(f"JWT验证通过，用户ID: {user_id}")
            
            # 将字符串类型的user_id转换为整数
            user_id = int(user_id)
            
            # 检查用户是否为管理员
            admin = Admin.query.filter_by(id=user_id).first()
            if not admin:
                current_app.logger.debug(f"用户ID {user_id} 不是管理员")
                return jsonify({'code': 403, 'message': '权限不足', 'data': None}), 403
            
            if not admin.is_active:
                current_app.logger.debug(f"管理员ID {user_id} 已被禁用")
                return jsonify({'code': 403, 'message': '账号已被禁用', 'data': None}), 403
            
            g.admin_id = user_id
            g.current_admin = admin
            return f(*args, **kwargs)
        except Exception as e:
            current_app.logger.error(f"管理员权限验证异常: {str(e)}")
            return jsonify({'code': 401, 'message': '请先登录', 'data': None}), 401
    return decorated